#include "visualosc.h"
#include "soc_comm.h"

#define DATA_OFFSET 6

static bool m_enabled = TRUE;
static uint8_t m_oscUartID = 0;
static uint8_t m_sendBuf[64 + 8]; //8 INFO
static uint8_t m_DataLen = 0;

#define ADD_BYTE_DATA(b) m_sendBuf[DATA_OFFSET + m_DataLen++] = b

void WriteToStream(const uint8_t *buf, int len)
{
    if(m_enabled)
        SOC_UartSend(m_oscUartID, buf, len);
}

void VisualOSCSetEnable(bool en)
{
    m_enabled = en;
}

void VisualOSCConfig(int uartId)
{
    m_oscUartID = uartId;
}

static void __NimingSendCurveBufferImpl(int ch)
{
    //0xF1-0XFA
    uint8_t cmd = 0xF1 + ch;
    uint8_t index = 0;
    uint8_t sum = 0, addsum = 0;
    uint8_t i;

    if(ch >= 10)
        return;

    m_sendBuf[index++] = 0xAB;
    m_sendBuf[index++] = 0x00;
    m_sendBuf[index++] = 0x00;
    m_sendBuf[index++] = cmd;
    m_sendBuf[index++] = m_DataLen & 0xff;
    m_sendBuf[index++] = (m_DataLen >> 8) & 0xff;

    index += m_DataLen;

    for (i = 0; i < index; i++)    
    {
        sum += m_sendBuf[i];
        addsum += sum;
    }
    m_sendBuf[index++] = sum;
    m_sendBuf[index++] = addsum;

    WriteToStream(m_sendBuf, index);
}

void NimingSendCurveByte(int ch, uint8_t val)
{
    m_DataLen = 0;
    NimingBufferAddByte(val);
    __NimingSendCurveBufferImpl(ch);
}

void NimingSendCurveInt16(int ch, uint16_t val)
{   
    m_DataLen = 0;
    NimingBufferAddInt16(val);
    __NimingSendCurveBufferImpl(ch);
}

void NimingSendCurveInt32(int ch, uint32_t val)
{
    m_DataLen = 0;
    NimingBufferAddInt32(val);
    __NimingSendCurveBufferImpl(ch);
}

void NimingSendCurveFloat(int ch, float val)
{
    m_DataLen = 0;
    NimingBufferAddFloat(val);
    __NimingSendCurveBufferImpl(ch);
}

void NimingSendCurveBuffer(int ch, uint8_t *buf, int len)
{
    uint8_t i;

    m_DataLen = 0;
    for(i = 0; i < len; i++)
    {
        ADD_BYTE_DATA(buf[i]);
    }

    __NimingSendCurveBufferImpl(ch);
}

void NimingSendCurveBufferPacket(int ch)
{
    __NimingSendCurveBufferImpl(ch);
}

void NimingResetBuffer()
{
    m_DataLen = 0;
}

void NimingBufferAddByte(uint8_t val)
{
    ADD_BYTE_DATA(val); 
}

void NimingBufferAddInt16(uint16_t val)
{
    ADD_BYTE_DATA(val & 0xff);
    ADD_BYTE_DATA((val >> 8) & 0xff);
}

void NimingBufferAddInt32(uint32_t val)
{
    ADD_BYTE_DATA(val & 0xff);
    ADD_BYTE_DATA((val >> 8) & 0xff);
    ADD_BYTE_DATA((val >> 16) & 0xff);
    ADD_BYTE_DATA((val >> 24) & 0xff);
}

void NimingBufferAddFloat(float val)
{   
    uint8_t *ptr = (uint8_t*)&val;

    ADD_BYTE_DATA(ptr[3]);
    ADD_BYTE_DATA(ptr[2]);
    ADD_BYTE_DATA(ptr[1]);
    ADD_BYTE_DATA(ptr[0]);
}
